package JavaEE.ManyThread5;
import java.util.Scanner;

// wait()和notify()的作用
// wait: "我睡了，钥匙给你（释放锁），记得叫我！"
// notify: "醒醒！该干活了！"（但必须由另一个线程来喊）
// 没法在同一个线程中,又调用wait,又调用notify!!!
public class Demo1 {
    public static Object locker = new Object();
    public static void main(String[] args) throws InterruptedException{
        Thread t1 = new Thread(() -> {
            System.out.println("locker等待之前");
            synchronized (locker) {
                try {
                    // 在t1中使用locker.wait代表:
                    // 将t1设置成"阻塞状态",并且"释放locker锁"
                    // (将t1放入locker的等待队列)
                    locker.wait();
                    // 处理中断异常
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            }
            System.out.println("locker等待之后");
        });
        Thread t2 = new Thread(() -> {
            Scanner in = new Scanner(System.in);
            System.out.println("请输入随意数据,以唤醒locker");
            in.next();
            synchronized (locker){
                // 从locker的等待队列中随机选择一个线程唤醒
                locker.notify();
                // 但此时不会立即释放锁,因为:
                // 调用notify()时,t2正持有locker锁,
                // 被唤醒的t1将会尝试重新获取locker锁,但必须等到t2释放锁后,t1才能拿得到
            }
        });
        t1.start();
        t2.start();
    }
}
//                               ---sleep和wait的区别?---
//              wait:                                     sleep:
// 所属类:     Object类的方法                           |  Thread类的方法
// 锁处理:     调用时会'释放锁'                          |  调用时不会释放锁
//  唤醒:    必须被其他线程调用notify()"也可以设置超时时间"  |  时间到,自动唤醒
// 使用场景:  线程间通信                                 |  单纯暂停线程
// 异常处理:  必须捕获InterruptedException              | 必须捕获InterruptedException
//                             (wait放锁等通知,sleep抱着锁睡觉)

